# encoding: UTF-8

"""
本文件仅用于存放对于事件类型常量的定义。
行情服务器：接受行情订阅（提供外部可调用的subscribe,或者响应REQ_QT_SUBSCRIBE类型的事件），
分发行情数据（将收到的DepthMarketData转换成TickData,作为EVENT_TICK类型事件的数据）
交易服务器：接受委托（OrderInsert、OrderAction)、查询(各类RQ事件），
返回委托（RTN）、成交（RTN）、查询结果（RSP）
数据服务器：处理行情数据（订阅交易标的行情、生成分钟数据、保存数据）,分发策略订阅的标的行情
策略服务器：订阅交易标的的行情数据（REQ_QT_SUBSCRIBE），接收行情数据（on_tick)，
分发策略信号(put)
风控服务器：接收行情数据、策略信号，计算交易头寸、止损出场价位，发送委托请求（交易信号）

事件命名规范说明：
相关缩写的意义：
QT:quote,行情相关
TD:trade，交易相关
MKT:market,市场相关
ACC:account, 账户相关
RM:risk management,风险管理相关，头寸计算、止损价格设置
DB:database, 数据存储相关
REQ:请求(CONNECT, LOGIN, LOGOUT, ORDER_INSERT, ORDER_ACTION(DELETE,AMEND), SUBSCRIBE,
UNSUBSCRIBE,SETTLEMENT_INFO_CONFIRM,AUTHENTICATE)
RTN:系统自动回报:
委托(包括下单、撤单、改单）后：RTN_ORDER（报单状态发生变化时）, RTN_ORDER_INSERT（报单请求出现错误时）
成交后：RTN_TRADE
RQ(REQ_QRY):查询请求
QRY:查询
RSP:查询请求应答

QuoteGateway事件：
发送的事件：
连接 / 断开 = EVENT_CONNECTED : 数据 True/False
登录 / 登出 = EVENT_LOGIN : 数据 True/False
Tick数据 = EVENT_TICK : 数据 TickData
Bar数据 = EVENT_BAR : 数据 BarData
接收的事件：
连接 = EVENT_RQ_CONNECT : 数据 QT_Address
登录 = EVENT_RQ_LOGIN ：数据 CtpLoginInfo
登出 = EVENT_RQ_LOGOUT
单一合约订阅 = EVENT_REQ_SUBSCRIBE ：数据 instrument_id
多合约订阅 = EVENT_REQ_SUBSCRIBES  : 数据 instrument_id 列表
单一合约退订 = EVENT_REQ_UNSUBSCRIBE ：数据 instrument_id
多合约退订 = EVENT_REQ_UNSUBSCRIBES  : 数据 instrument_id 列表

TradeGateway事件：
发送的事件：
连接 / 断开 = EVENT_CONNECTED : 数据 True/False
登录 / 登出 = EVENT_LOGIN : 数据 True/False
系统认证 =
Tick数据 = EVENT_TICK : 数据 TickData
账户信息 =
持仓 =
持仓明细 =
成交 =
委托 =


接收的事件：
连接 = EVENT_RQ_CONNECT : 数据 QT_Address
登录 = EVENT_RQ_LOGIN ：数据 CtpLoginInfo
系统认证 =
登出 = EVENT_RQ_LOGOUT
单一合约查询 = EVENT_REQ_SUBSCRIBE ：数据 instrument_id

由于python中不存在真正的常量概念，因此选择使用全大写的变量名来代替常量。
这里设计的命名规则以EVENT_前缀开头。

常量的内容通常选择一个能够代表真实意义的字符串（便于理解）。

建议将所有的常量定义放在该文件中，便于检查是否存在重复的现象。
"""
# 行情和交易共用事件
# 连接相关
EVENT_CONNECTED = 'eConnected.'  # 后接QT  QT ，数据为True/False,分别表示：行情已连接、未连接，交易已连接、未连接
EVENT_QT_CONNECTED = 'eQTConnected'  # 数据为True/False,表示：行情已连接、未连接
EVENT_TD_CONNECTED = 'eTDConnected'  # 数据为True/False,表示：交易已连接、未连接
EVENT_REQ_CONNECT = 'eReqConnect.'  # 后接QT  TD，数据类型为CTPLoginInfo,表示请求行情连接、交易连接
EVENT_REQ_QT_CONNECT = 'eReqQTConnect'  # 数据类型为CTPLoginInfo,表示请求行情连接
EVENT_REQ_TD_CONNECT = 'eReqTDConnect'  # 数据类型为CTPLoginInfo,表示请求交易连接
EVENT_DAY_DATA = 'eDayData'  # 日数据
# 登录相关
EVENT_LOGIN = 'eLogin.'  # 后接QT TD，数据为True/False,分别表示：行情已登录、未登录，交易已登录、未登录
EVENT_QT_LOGIN = 'eQTLogin'  # 数据为True/False,表示：行情已登录、未连接
EVENT_TD_LOGIN = 'eTDLogin'  # 数据为True/False,表示：交易已连接、未连接
EVENT_REQ_LOGIN = 'eReqLogin.'  # 后接QT  TD，数据类型为CTPLoginInfo,表示请求行情登录、交易登录
EVENT_REQ_QT_LOGIN = 'eReqQTLogin'  # 数据类型为CTPLoginInfo,表示请求行情登录
EVENT_REQ_TD_LOGIN = 'eReqTDLogin'  # 数据类型为CTPLoginInfo,表示请求交易登录
EVENT_REQ_LOGOUT = 'eREQLogout.'  # 后接QT  TD，表示请求行情退出、交易退出
EVENT_REQ_QT_LOGOUT = 'eReqQTLogout'  # 表示请求行情退出、交易退出
EVENT_REQ_TD_LOGOUT = 'eReqTDLogout'  # 表示请求交易退出
EVENT_RTN_ERROR = 'eRtnError.'  # 错误回报事件 ,后接QT  TD
EVENT_REQ_SUBSCRIBE_TRADING_INSTRUMENT = 'eReqSubscribeTradingInstrument'  #
EVENT_REQ_SUBSCRIBE = 'eReqSubscribe.'  # 行情订阅事件，dict_['data']=symbol，对交易来说，是即时行情查询
EVENT_REQ_QT_SUBSCRIBE = 'eReqQTSubscribe'  # 行情服务器上的行情订阅事件，dict_['data']=symbol
EVENT_REQ_TD_SUBSCRIBE = 'eReqTDSubscribe'  # 交易服务器上的即时行情查询, dict_['data']=symbol
EVENT_REQ_UNSUBSCRIBE = 'eReqUnSubscribe'  # 行情退订事件，dict_['data']=symbol， 交易不存在该类型事件
EVENT_REQ_SUBSCRIBES = 'eReqSubscribes'  # 行情订阅事件，dict_['data']=symbol list
EVENT_REQ_UNSUBSCRIBES = 'eReqUnSubscribes'  # 行情退订事件，dict_['data']=symbol list， 交易不存在该类型事件
EVENT_RTN_DEPTH_DATA = 'eRtnDepthMarketData.'  # 订阅或查询返回的数据,后接QT、TD表示行情订阅或交易查询的返回
EVENT_RSP_DEPTH_MARKET_DATA = 'eRspDepthMarketData.'
EVENT_RSP_DEPTH_MARKET_DATA_CTP = 'eRspDepthMarketDataCTP'
# 系统相关
EVENT_TIMER = 'eTimer'  # 计时器事件，每隔1秒发送一次
EVENT_LOG = 'eLog'  # 日志事件，全局通用
EVENT_REQ_AUTH = 'eReqAuth'  # 请求系统认证事件，只有交易系统有
EVENT_RSP_AUTH = 'eRspAuth'  # 系统认证事件应答，只有交易系统有
EVENT_RQ_SETTLEMENT_INFO = 'eRQSettlementInfo'  # 结算单查询，只有交易系统有
EVENT_RSP_SETTLEMENT_INFO = 'eRspSettlementInfo'  # 结算单查询应答，只有交易系统有
EVENT_REQ_SETTLEMENT_CONFIRM = 'eReqSettlementConfirm'  # 结算单确认请求事件，只有交易系统有
EVENT_RSP_SETTLEMENT_CONFIRM = 'eRspSettlementConfirm'  # 结算单确认应答，只有交易系统有

EVENT_TQ_ORDER = 'eTqOrder.'  # 天勤委托变动
EVENT_TQ_ACCOUNT = 'eTqAccount.'
EVENT_TQ_TRADE = 'eTqTrade.'
EVENT_TQ_POSITION = 'eTqPosition.'
EVENT_TQ_TICK = 'eTQTick.'  # 天勤行情
EVENT_TQ_BAR = 'eTQBar.'

# Gateway相关
EVENT_TICK = 'eTick.'  # TICK行情事件，可后接具体的vtSymbol，由QuoteGateway激活，
EVENT_BAR = 'eBar.'  # Bar行情事件，可后接具体的vtSymbol，由DrEngine激活

# 交易账户相关
EVENT_REQ_ORDER_INSERT = 'eReqOrderInsert'  # 委托请求
EVENT_REQ_ORDER_DELETE = 'eReqOrderDelete'  # 撤单请求
EVENT_REQ_ORDER_ACTION = 'eReqOrderAction.'  # 改单请求，后接 Delete, Amend
EVENT_RTN_ORDER = 'eRtnOrder.'  # 报单回报事件，来源于 EVENT_REQ_ORDER_INSERT, 和 EVENT_REQ_ORDER_ACTION
EVENT_RTN_TRADE = 'eRtnTrade.'  # 成交回报事件，当委托成交时，CTP系统自动处理的回报

# 查询及应答
EVENT_RQ_TRADE = 'eRQTrade.'  # 成交查询请求，数据为：'broker_id':'','investor_id':''
EVENT_RSP_TRADE = 'eRspTrade'  # 成交查询应答
EVENT_UNTRADE = 'eUnTrade.'  # 未成交回报事件
EVENT_RQ_ACCOUNT = 'eRQAccount'  # 账户查询请求，数据为：'broker_id':'','investor_id':''
EVENT_RSP_ACCOUNT = 'eRspAccount.'  # 账户查询应答事件，来源于 EVENT_RQ_ACCOUNT
EVENT_RQ_POSITION = 'eRQPosition'  # 持仓查询请求，数据为：'broker_id':'','investor_id':''
EVENT_RSP_POSITION = 'eRspPosition.'  # 持仓查询应答事件
EVENT_RQ_POSITION_DETAIL = 'ERQPositionDetail'  # 持仓明细查询请求，数据为：'broker_id':'','investor_id':''
EVENT_RSP_POSITION_DETAIL = 'eRspPositionDetail.'  # 持仓明细查询应答事件
EVENT_RQ_ORDER = 'eRQOrder'  # 报单查询请求，数据为：'broker_id':'','investor_id':''
EVENT_RSP_ORDER = 'eRspOrder.'  # 报单查询回报事件 QRY RSP RSPQRY
EVENT_RQ_INSTRUMENT = 'eRQInstrument'  # 标的查询请求，数据为：'instrument_id':'','market_id':''
EVENT_RSP_INSTRUMENT = 'eRspInstrument.'  # 标的基础信息回报事件
EVENT_RQ_INSTRUMENT_MARGIN = 'eRQInstrumentMargin'  # 合约保证金查询请求，数据为：'instrument_id':''
EVENT_RSP_INSTRUMENT_MARGIN = 'eRspInstrumentMargin.'  # 标的保证金信息回报事件
EVENT_RQ_INSTRUMENT_FEE = 'eRQInstrumentFee'  # 标的费用（率）查询请求，数据为：'instrument_id':''
EVENT_RSP_INSTRUMENT_FEE = 'eRspInstrumentFee'  # 标的费用（率）信息回报事件
EVENT_RSP_CONTRACT = 'eRspContract.'  # 合约基础信息回报事件
EVENT_RQOK_INSTRUMENT = 'eRspQryInstrumentOK'  # 标的查询应答结束
EVENT_RQOK_INSTRUMENT_FEE = 'eRspQryInstrumentFeeOK'  # 标的费用（率）查询应答结束
EVENT_RQOK_INSTRUMENT_MARGIN = 'eRspQryInstrumentMarginOK'  # 标的保证金率查询应答结束
# 银期事件
EVENT_REQ_BANK_FUTURE = 'eReqBankToFuture.'  # 银行向期资转账
EVENT_REQ_FUTURE_BANK = 'eReqFutureBankTo.'  # 期货资金账户向银行转账
# CTP原数据，未经处理
EVENT_RSP_ACCOUNT_CTP = EVENT_RSP_ACCOUNT + 'CTP'  # 账户查询应答事件，来源于 EVENT_RQ_ACCOUNT
EVENT_RSP_POSITION_CTP = EVENT_RSP_POSITION + 'CTP'  # 持仓查询应答事件
EVENT_RSP_POSITION_DETAIL_CTP = EVENT_RSP_POSITION_DETAIL + 'CTP'  # 持仓明细查询应答事件
EVENT_RTN_ORDER_CTP = EVENT_RTN_ORDER + 'CTP'  # 报单回报事件，来源于 EVENT_REQ_ORDER_INSERT, 和 EVENT_REQ_ORDER_ACTION
EVENT_RTN_TRADE_CTP = EVENT_RTN_TRADE + 'CTP'  # 成交回报事件，当委托成交时，CTP系统自动处理的回报
EVENT_RSP_INSTRUMENT_CTP = EVENT_RSP_INSTRUMENT + 'CTP'  # 标的基础信息回报事件
EVENT_RSP_INSTRUMENT_MARGIN_CTP = EVENT_RSP_INSTRUMENT_MARGIN + 'CTP'  # 标的保证金信息回报事件
EVENT_RSP_INSTRUMENT_FEE_CTP = EVENT_RSP_INSTRUMENT_FEE + 'CTP'  # 标的费用（率）信息回报事件
EVENT_RSP_TRADE_CTP = EVENT_RSP_TRADE + 'CTP'  # 成交查询应答
EVENT_RSP_ORDER_CTP = EVENT_RSP_ORDER + 'CTP'  # 成交查询应答
# 策略模块相关
### 由策略发起，策略引擎或者数据引擎响应
EVENT_RSP_TICKS = 'eTicks.'  # 后跟symbol,数据为pd.DataFrame(columns=['datetime','last_price','volume'])
EVENT_RSP_BARS = 'eBars.'  # 后跟symbol,数据为pd.DataFrame(columns=['datetime','open','high','low','close','volume'])
EVENT_PARAMS = 'eParams.'  # 后跟 策略实例名称 , 数据为 Params 字典
EVENT_REQ_TICKS = 'eReqTicks.'  # 后跟symbol,数据为 {symbol,start_datetime,end_datetime}
EVENT_REQ_BARS = 'eReqBars.'  # 后跟symbol,数据为 {symbol,start_datetime,end_datetime}
EVENT_REQ_PARAMS = 'eReqParams.'  # 后跟 策略实例名称 , 数据为 策略实例名称

EVENT_CTA_LOG = 'eCtaLog'  # CTA相关的日志事件
EVENT_CTA_STRATEGY = 'eCtaStrategy.'  # CTA策略状态变化事件
EVENT_STRATEGY = 'eStrategy.'  # CTA策略状态变化事件
EVENT_STRATEGY_SIGNAL = 'eStrategySignal.'  # 后跟策略名称，数据为策略信号：TradeSignal
EVENT_STRATEGY_INIT = 'eStrategyInit.'  # 策略初始化事件 ，后跟策略名称:策略类名_标的代码_使用周期
EVENT_STRATEGY_START = 'eStrategyStart.'  # 策略启动事件，后跟策略名称
EVENT_STRATEGY_STOP = 'eStrategyStop.'  # 策略停止事件，后跟策略名称
EVENT_STRATEGY_ERROR = 'eStrategyError.'  # 错误事件
EVENT_STOPLOSSORDER = 'eStopLossOrder.'  # 策略止损委托事件，后跟symbol(instrumentID),由RMEngine激发
EVENT_BACKTEST_ORDER = 'eStrategyBackTestOrder.'  # 策略回测
EVENT_BACKTEST_RESULT = 'eBacktestResult.'  # 策略回测结果
EVENT_STRATEGY_HISTORY_SIGNALS = 'eStrategyHistorySignals.'  # 历史数据策略信号事件，后跟策略实例名称，数据是策略信号字典,key:信号发生时间
EVENT_TO_ORDER = 'eToOrder.'  # 要委托的订单，数据类型：TradeSignal
# 行情记录模块相关
EVENT_DATARECORDER_LOG = 'eDataRecorderLog'  # 行情记录日志更新事件

# Wind接口相关
EVENT_REQ_WIND_CONNECT = 'eReqWindConnect'  # Wind接口请求连接事件

EVENT_TRADE = 'eTrade.'
EVENT_ORDER = 'eOrder.'
EVENT_POSITION = 'ePosition.'
EVENT_ACCOUNT = 'eAccount.'
EVENT_INSTRUMENT='eInstrument.'

# ----------------------------------------------------------------------
def dup_test():
    """检查是否存在内容重复的常量定义"""
    check_dict = {}

    global_dict = globals()

    for key, value in global_dict.items():
        if '__' not in key:  # 不检查python内置对象
            if value in check_dict:
                check_dict[value].append(key)
            else:
                check_dict[value] = [key]

    for key, value in check_dict.items():
        if len(value) > 1:
            print(u'存在重复的常量定义:' + str(key))
            for name in value:
                print(name)
            print('')

    print(u'测试完毕')



EVENT_FrontConnected = 'eFrontConnected.'
EVENT_FrontDisconnected = 'eFrontDisconnected.'
EVENT_HeartBeatWarning = 'eHeartBeatWarning.'
EVENT_RspUserLogin = 'eRspUserLogin.'
EVENT_RspUserLogout = 'eRspUserLogout.'
EVENT_RspError = 'eRspError.'
EVENT_RspSubMarketData = 'eRspSubMarketData.'
EVENT_RspUnSubMarketData = 'eRspUnSubMarketData.'
EVENT_RspSubForQuoteRsp = 'eRspSubForQuoteRsp.'
EVENT_RspUnSubForQuoteRsp = 'eRspUnSubForQuoteRsp.'
EVENT_RtnDepthMarketData = 'eRtnDepthMarketData.'
EVENT_RtnForQuoteRsp = 'eRtnForQuoteRsp.'


class QuoteEventType:
    FrontConnected = 'eFrontConnected.'
    FrontDisconnected = 'eFrontDisconnected.'
    HeartBeatWarning = 'eHeartBeatWarning.'
    RspUserLogin = 'eRspUserLogin.'
    RspUserLogout = 'eRspUserLogout.'
    RspError = 'eRspError.'
    RspSubMarketData = 'eRspSubMarketData.'
    RspUnSubMarketData = 'eRspUnSubMarketData.'
    RspSubForQuoteRsp = 'eRspSubForQuoteRsp.'
    RspUnSubForQuoteRsp = 'eRspUnSubForQuoteRsp.'
    RtnDepthMarketData = 'eRtnDepthMarketData.'
    RtnForQuoteRsp = 'eRtnForQuoteRsp.'


# 直接运行脚本可以进行测试
if __name__ == '__main__':
    import datetime

    dtn = datetime.datetime.now()
    print(type(dtn), dtn)
    dtns = dtn.strftime('%Y-%m-%d %H:%M:%S.%f')
    print(type(dtns), dtns)
    dup_test()
